home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Games / Game Sample Code / ZAM 1.0a13 / GameSource / SpriteFrameSet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-16  |  9.2 KB  |  325 lines  |  [TEXT/KAHL]

  1. #include "ZAMProtos.h"
  2.  
  3.  
  4. void InitFrameSetInfo(frameSetPtr fsp, short frameCount)
  5. /* initialize the frame set header */
  6. /* this is the stuff that is block moved around when a sprite frame set is shared */
  7. /* not a good way to do it. */
  8. {
  9.     fsp->finfo.frameCount = frameCount;
  10.     fsp->finfo.frameIndex = 0;
  11.     fsp->finfo.curImage = &fsp->flist[0];
  12.     fsp->finfo.prevImage = fsp->finfo.curImage;
  13.     fsp->finfo.dimension.h = RECT_WD(fsp->flist[0].image->portRect);
  14.     fsp->finfo.dimension.v = RECT_HT(fsp->flist[0].image->portRect);
  15.     fsp->finfo.center.h = fsp->finfo.dimension.h / 2;
  16.     fsp->finfo.center.v = fsp->finfo.dimension.v / 2;
  17. }
  18.  
  19.  
  20. void SetSpriteCurrentFrame(spritePtr theSprite, short frameNum)
  21. /*
  22.     Force the sprite to change frame. This also remembers the current frame
  23.     so that erasing happens correctly later.
  24. */
  25. {
  26.     theSprite->frameList->finfo.frameIndex = frameNum;
  27.     theSprite->frameList->finfo.prevImage = theSprite->frameList->finfo.curImage;
  28.     theSprite->frameList->finfo.curImage = &theSprite->frameList->flist[frameNum];
  29. }
  30.  
  31. OSErr CopyFrameSet(frameSetPtr srcFrameSet, frameSetPtr *destFrameSet)
  32. /*
  33.     This should be called duplicate or clone because it allocates
  34.     the destination frame set for you and copies the source to it.
  35. */
  36. {
  37.     frameSetPtr fsp;
  38.     long        fsSize;
  39.     OSErr        err = noErr;
  40.     
  41.     
  42.     fsSize = sizeof(frameInfo) + (sizeof(frameCell) * srcFrameSet->finfo.frameCount);
  43.     
  44.     /* create a new frame set block -- this is the destination frame set */
  45.     fsp = (frameSetPtr)NewPtrClear(fsSize);
  46.     if(fsp == nil) {
  47.         err = MemError();
  48.         ErrMsgCode("\pError allocating SpriteFrameSet",err);
  49.     }
  50.     
  51.     if(err == noErr) {
  52.         BlockMove(srcFrameSet, fsp, fsSize);
  53.     }
  54.     
  55.     *destFrameSet = fsp;
  56.     
  57.     return err;
  58. }
  59.  
  60. OSErr CreateEmptyFrameSet(frameSetPtr *dstFrameSet, short numFrames)
  61. /*
  62.     This creates a frame set with no actual content.  
  63.     Content can be copied later with SetSpriteFrameSet, which is the nasty block move
  64.     culprit.
  65. */
  66. {
  67.     frameSetPtr fsp;
  68.     long        fsSize;
  69.     OSErr        err = noErr;
  70.  
  71.     fsSize = sizeof(frameInfo) + (sizeof(frameCell) * numFrames);
  72.     
  73.     /* create a new frame set block -- this is the destination frame set */
  74.     fsp = (frameSetPtr)NewPtrClear(fsSize);
  75.     if(fsp == nil) {
  76.         err = MemError();
  77.         ErrMsgCode("\pError allocating SpriteFrameSet",err);
  78.     }
  79.  
  80.     if(err == noErr) {
  81.         fsp->finfo.frameCount = numFrames;
  82.         fsp->finfo.frameIndex = 0;
  83.         fsp->finfo.curImage = nil;
  84.         fsp->finfo.prevImage = nil;
  85.     }
  86.  
  87.     *dstFrameSet = fsp;
  88.     
  89.     return err;
  90. }
  91.  
  92. void SetSpriteFrameSet( spritePtr theSprite, frameSetPtr srcFrameSet)
  93. /*
  94.     Change the frame set of a sprite from whatever it was to the new one.
  95.     
  96.     Note that this has one severe limiation, in that you can only go to another
  97.     frame set that has the same number of frames.   This function could be changed
  98.     to check for a difference in size and deal with it, but it is actually pretty
  99.     weak as it is already, and a completely different scheme would work better.
  100.     A frame set reference perhaps or something like that.
  101. */
  102. {
  103.     long            fsSize;
  104.     frameCellPtr    prevFrameSet;
  105.     
  106.     fsSize = GetPtrSize(srcFrameSet);
  107.     /* save the previous frame set for erasing the old image */
  108.     prevFrameSet = theSprite->frameList->finfo.curImage;
  109.  
  110.     /* copy the new frame set over the first one, and set it to the start */
  111.     BlockMove(srcFrameSet, theSprite->frameList, fsSize);
  112.     InitFrameSetInfo(theSprite->frameList, srcFrameSet->finfo.frameCount);
  113.  
  114.     /* if there was a previous frame set, then restore it */
  115.     if(prevFrameSet != nil)
  116.         theSprite->frameList->finfo.prevImage = prevFrameSet;
  117. }
  118.  
  119. OSErr CreateColorIconFrameSet(frameSetPtr *newFrameSet, short startID, short numFrames)
  120. /*
  121.     Create a frame set from color icons starting with CICN resource id startID for the numFrames.
  122. */
  123. {
  124.     short            index;
  125.     frameSetPtr        fsp;
  126.     frameCellPtr    fcp;
  127.     short            err = noErr;
  128.     CIconHandle        cicn;
  129.     
  130.     /* create a new frame set block */
  131.     fsp = (frameSetPtr)NewPtrClear(sizeof(frameInfo) + (sizeof(frameCell) * numFrames));
  132.     if(fsp == nil) {
  133.         err = MemError();
  134.         ErrMsgCode("\pError allocating SpriteFrameSet",err);
  135.     }
  136.     if(err == noErr) {
  137.         /* load the frames into the GWorld list */
  138.         for(index = 0; (index < numFrames) && (err == noErr); index ++) {
  139.             fcp = &fsp->flist[index];
  140.             cicn = GetCIcon(startID + index);
  141.             if(cicn == nil) {
  142.                 err = ResError();
  143.                 ErrMsgCode("\pcicn resource not loaded in CreateColorIconFrameSet",err);
  144.             } else {
  145.                 err = CreateGWorldFromCIcon(&fcp->image, cicn);
  146.                 if(err != noErr) {
  147.                     ErrMsgCode("\pCreateColorIconFrameSet: CreateGWorldFromCIcon failed.",err);
  148.                 }
  149.                 if(err == noErr) {    
  150.                     err = CreateRegionFromCIconMask(&fcp->mask, cicn);
  151.                     if(err != noErr) {
  152.                         ErrMsgCode("\pCreateRegionFromCIconMask failed.",err);
  153.                     } else {
  154.                         /* save off the topleft of the region so we can move */
  155.                         /* it with the sprite */
  156.                         fcp->maskLoc.v = (**fcp->mask).rgnBBox.top;
  157.                         fcp->maskLoc.h = (**fcp->mask).rgnBBox.left;
  158.                     }
  159.                 }
  160.                 DisposeCIcon(cicn);
  161.             }
  162.         }
  163.         /* have all the frames, so set up the frame header information */
  164.         InitFrameSetInfo(fsp, numFrames);
  165.     }
  166.     
  167.     *newFrameSet = fsp;
  168.  
  169.     if(err != noErr) {
  170.         /* crappy for now but hey */
  171.         ErrMsgCode("\pIt would be unwise to proceed.!!!",err);
  172.         ExitToShell();
  173.     }
  174.     
  175.     return err;
  176.  
  177. }
  178.  
  179.  
  180. OSErr CreatePICTIconFrameSet(frameSetPtr *newFrameSet, short startID, short numFrames)
  181. /*
  182.     Does the same thing, only the image is loaded from a picture while
  183.     the mask is loaded from a cicn.  The reason for this is that I originally was only using
  184.     cicns, but, then I discovered a lovely program called DeBabelizer 
  185.     ( by Equilibrium Technologies, in Sausalito, CA), which will take a whole bunch of art work
  186.     from just about anywhere and create a common palette for it, and even re-map the pictures to the
  187.     new palette.  So I did that with all the artwork in ZAM, but did not want to take it from the PICTs
  188.     back to CICN.  Too bad Debabelizer cannot process CICNS directly.
  189.     So this is a hacky way around it, and I'm sorry to say it takes up more room on disk.
  190. */
  191. {
  192.     short            index;
  193.     frameSetPtr        fsp;
  194.     frameCellPtr    fcp;
  195.     short            err = noErr;
  196.     CIconHandle        cicn;
  197.     PicHandle        pict;
  198.     
  199.     /* create a new frame set block */
  200.     fsp = (frameSetPtr)NewPtrClear(sizeof(frameInfo) + (sizeof(frameCell) * numFrames));
  201.     if(fsp == nil) {
  202.         err = MemError();
  203.         ErrMsgCode("\pError allocating SpriteFrameSet",err);
  204.     }
  205.     if(err == noErr) {
  206.         /* load the frames into the GWorld list */
  207.         for(index = 0; (index < numFrames) && (err == noErr); index ++) {
  208.             fcp = &fsp->flist[index];
  209.             cicn = GetCIcon(startID + index);
  210.             if(cicn == nil) {
  211.                 err = ResError();
  212.                 ErrMsgCode("\pcicn resource not loaded in CreateColorIconFrameSet",err);
  213.             } else {
  214.                 pict = GetPicture(startID + index);
  215.                 if(pict == nil) {
  216.                     err = ResError();
  217.                     ErrMsgCode("\pPICT resource not loaded in CreateColorIconFrameSet",err);
  218.                 } else {
  219.                     err = CreateGWorldFromPict(&fcp->image, pict);
  220.                     if(err != noErr) {
  221.                         ErrMsgCode("\pCreateColorIconFrameSet: CreateGWorldFromPict failed.",err);
  222.                     }
  223.                     if(err == noErr) {    
  224.                         err = CreateRegionFromCIconMask(&fcp->mask, cicn);
  225.                         if(err != noErr) {
  226.                             ErrMsgCode("\pCreateRegionFromCIconMask failed.",err);
  227.                         } else {
  228.                             /* save off the topleft of the region so we can move */
  229.                             /* it with the sprite */
  230.                             fcp->maskLoc.v = (**fcp->mask).rgnBBox.top;
  231.                             fcp->maskLoc.h = (**fcp->mask).rgnBBox.left;
  232.                         }
  233.                     }
  234.                     ReleaseResource(pict);
  235.                 }
  236.                 DisposeCIcon(cicn);
  237.             }
  238.         }
  239.         /* have all the frames, so set up the frame header information */
  240.         InitFrameSetInfo(fsp, numFrames);
  241.     }
  242.     
  243.     *newFrameSet = fsp;
  244.  
  245.     if(err != noErr) {
  246.         /* crappy for now but hey */
  247.         ErrMsgCode("\pIt would be unwise to proceed.!!!",err);
  248.         ExitToShell();
  249.     }
  250.     
  251.     return err;
  252.  
  253. }
  254.  
  255. short GetNextSpriteFrameIndex(spritePtr spr)
  256. {
  257.     short    frameNum;
  258.  
  259.     frameNum = spr->frameList->finfo.frameIndex + 1;
  260.  
  261.     if(frameNum >= spr->frameList->finfo.frameCount) {
  262.         frameNum    = 0;
  263.     }
  264.     
  265.     return frameNum;
  266. }
  267.  
  268.  
  269. void AttachCTableToFrameSet(frameSetPtr frameSet, CTabHandle srcCtable, short ctSeed)
  270. /*
  271.     Change the color table of a frame set, and set the seed.  I had mixed results using this.
  272. */
  273. {
  274.     CTabHandle        ctab;
  275.     frameCellPtr    prevFrameSet;
  276.     short            i;
  277.     PixMapHandle    pmH;
  278.     
  279.     
  280.     ctab = srcCtable;
  281.  
  282.     for(i = 0; i < frameSet->finfo.frameCount; i++) {
  283.         pmH = GetGWorldPixMap(frameSet->flist[i].image);        // get pixmap
  284.         DisposeHandle((**pmH).pmTable);
  285.         HandToHand(&ctab);                                        // duplicate it
  286.         (**pmH).pmTable = ctab;                                    // stuff it in
  287.         (**(**pmH).pmTable).ctSeed = ctSeed;                    // change the seed
  288.     } 
  289.     
  290. }
  291.  
  292.  
  293. void SetFrameSetCTSeed(frameSetPtr frameSet, short newSeed)
  294. {
  295.     short            i;
  296.     PixMapHandle    pmH;
  297.  
  298.     for(i = 0; i < frameSet->finfo.frameCount; i++) {
  299.         pmH = GetGWorldPixMap(frameSet->flist[i].image);        // get pixmap
  300.         (**(**pmH).pmTable).ctSeed = newSeed;                    // change the seed
  301.     } 
  302. }
  303.  
  304. void SetSpriteXXFrameSet( spritePtr theSprite, frameSetPtr srcFrameSet)
  305. /*
  306.     Guess this is old dead code no longer used.
  307. */
  308. {
  309.     long            fsSize;
  310.     frameCellPtr    prevFrameSet;
  311.     
  312.     fsSize = GetPtrSize(srcFrameSet);
  313.     /* save the previous frame set for erasing the old image */
  314.     prevFrameSet = theSprite->frameList->finfo.curImage;
  315.  
  316.     /* copy the new frame set over the first one, and set it to the start */
  317.     BlockMove(srcFrameSet, theSprite->frameList, fsSize);
  318.     InitFrameSetInfo(theSprite->frameList, srcFrameSet->finfo.frameCount);
  319.  
  320.     /* if there was a previous frame set, then restore it */
  321.     theSprite->frameList->finfo.prevImage = prevFrameSet;
  322. }
  323.  
  324.  
  325.